/**
 * Nombre del archivo: StackVector.java
 * Fecha de creacion: 12 de julio de 2012
 * Descripcion: impelementacion de la interfaz de la pila con vectores. Es genérica
 * Basado en la clase StackVector de Bailey en Java Structures p. 225 
 */

import java.util.Vector;

/**
 * @author Maria Fernanda Martinez
 * @param <G>
 */
public class StackVector <G> implements Stack <G> 
{ 
    
    /**
     * Estructura de datos: Vector
     * Tipo de datos: G
     * Descripcion: arreglo para guardar valores
     */
    protected Vector<G> data;

    /**
     * Nombre: StackVector
     * Descripcion: construye un vector
     * Pre: ninguno
     * Post: nuevo vector creado
     * Parametros: ninguno
     * Valor de retorno: ninguno
     */
    public StackVector()
    {
        data = new Vector<G>();    
    }
    
    /**
     * Nombre: StackVector
     * Descripcion: construye un vector con un tamaño especifico
     * Pre: ninguno
     * Post: vector de tamaño especifico creado
     * @param size de tipo int
     * Valor de retorno: ninguno
     */
    public StackVector(int size)
    {
        data=new Vector<G>(size);
    }

    /**
     * Nombre: push
     * Descripcion: agrega un objeto a la pila
     * Pre: espacio disponible
     * Post: item agregado a la pila
     * @param item de tipo G
     */
    @Override
    public void push(G item) 
    {
        data.add(item);
    }

    /**
     * Nombre: pop
     * Descripcion: el objeto que entro de ultimo a la pila es retirado de ella
     * Pre: hay item en la pila
     * Post: item removido de la pila
     * Parametros: ninguno
     * @return valor tipo G
     */
    @Override
    public G pop() 
    {
        return data.remove(size()-1);
    }

     /**
     * Nombre: peek
     * Descripcion: muestra el ultimo valor que ingreso a la pila
     * Pre: hay item en la pila
     * Post: ninguno (solo muestra item)
     * Parametros: ninguno
     * @return valor tipo G
     */
    @Override
    public G peek() 
    {
        return data.get(size()-1);
    }

    /**
     * Nombre: empty
     * Descripcion: regresa el valor true si la pila esta vacia
     * Pre: ninguno
     * Post: ninguno (solo regresa true/false)
     * Parametros: ninguno
     * @return valor tipo boolean
     */
    @Override
    public boolean empty() 
    {
        return size()==0;
    }
    
    /**
     * Nombre: size
     * Descripcion: obtiene la cantidad de elementos presentes en la pila
     * Pre: ninguno
     * Post: ninguno (solo regresa un numero)
     * Parametros: ninguno
     * @return valor tipo int
     */
    @Override
    public int size() 
    {
        return data.size();
    }
    
    /**
     * Nombre: operate
     * Descripcion: realiza la operacion con dos numeros basado en el operador ingresado
     * Pre: existen dos valores numericos y un operador
     * Post: resultado de la operacion
     * @param a de tipo float
     * @param b de tipo float
     * @param op de tipo String
     * @return valor tipo float
     */  
    @Override
    public float operate(float a, float b, String op){
        float result=0;
        if(op.equals("+")){
            result=a+b;
        }
        else if(op.equals("-")){
            result=a-b;
        }
        else if(op.equals("*")){
            result=a*b;
        }
        else if(op.equals("/")){
            if(b!=0){
                result=a/b;
            }
            else{
                System.out.println("Division por cero");
                result=0;
            }
        }
        return result;
    }
    
    /**
     * Basado en el ejemplo de http://lineadecodigo.com/java/validar-si-un-dato-es-numerico-en-java/
     * Nombre: isNumeric
     * Descripcion: regresa true si los caracteres de la cadena representan un numero
     * Pre: existe una cadena de caracteres
     * Post: ninguno (solo regresa true/false)
     * @param cadena de tipo String
     * @return valor tipo boolean
     */
    @Override
    public boolean isNumeric(String cadena){
	try {
            Float.parseFloat(cadena);
            return true;
	} catch (NumberFormatException nfe){
            return false;
	}
    }
    
    
    /**
     * Nombre: isSymbol
     * Descripcion: regresa true si la cadena ingresada es un operador
     * Pre: existe una cadena con un caracter
     * Post: ninguno (solo regresa true/false)
     * @param cadena de tipo String
     * @return  valor tipo boolean
     */
    @Override
    public boolean isSymbol(String cadena){
        if(cadena.equals("+")||cadena.equals("-")||cadena.equals("*")||cadena.equals("/")) {
            return true;
        }
        else
            return false;
    }
    
    /**
     * Nombre: clear
     * Descripcion: saca todos los elementos de la pila
     * Pre: ninguno
     * Post: pila vacia
     * Parametros: ninguno 
     * Valor de retorno: ninguno
     */
    public void clear()
    {
        data.clear();
    }
    
}
